package com.bfly.mall.order.service.impl;

import com.bfly.common.util.DateUtil;
import com.bfly.common.util.StringUtil;
import com.bfly.core.base.service.BaseServiceImpl;
import com.bfly.core.context.AdminThreadLocal;
import com.bfly.core.context.IpThreadLocal;
import com.bfly.core.enums.SysError;
import com.bfly.core.exception.ServiceResponseException;
import com.bfly.mall.admin.entity.Admin;
import com.bfly.mall.order.dto.OrderExpressFormDTO;
import com.bfly.mall.order.dto.OrderExpressNamesDTO;
import com.bfly.mall.order.entity.*;
import com.bfly.mall.order.enums.ExpressStatusEnum;
import com.bfly.mall.order.enums.OrderOpTypeEnum;
import com.bfly.mall.order.event.OrderShipEvent;
import com.bfly.mall.order.service.IOrderExpressService;
import com.bfly.mall.order.service.IOrderLogsService;
import com.bfly.mall.order.service.IOrderService;
import com.bfly.mall.product.enums.ShippingMethodEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 长沙商脉科技有限公司
 * @date 2020/4/19 19:05
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class OrderExpressServiceImpl extends BaseServiceImpl<OrderExpress, Integer> implements IOrderExpressService {

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderLogsService logsService;
    @Autowired
    private ApplicationContext applicationContext;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void shopKeeperShipOrder(Admin admin,OrderExpressFormDTO express) {
        Order order = orderService.getOrder(express.getOrderNo());
        if (!order.isCanShip()) {
            String message = String.format("状态为 %s %s %s 的订单不能做发货操作!", order.getStatusName(), order.getPayStatusName(), order.getExpressStatusName());
            throw new ServiceResponseException(SysError.ERROR, message);
        }

        ShippingMethodEnum typeEnum = ShippingMethodEnum.getShippingMethod(order.getDispatchId());
        if (typeEnum == null) {
            // 自提快递单号为当前发货时间 前缀是 ZT
            throw new ServiceResponseException(SysError.PARAM_ERROR, "发货类型错误!");
        }
        List<OrderExpress> expresses = new ArrayList<>();
        if (typeEnum == ShippingMethodEnum.EXPRESS) {
            List<OrderExpressNamesDTO> namesDTOList = express.getExpress();
            namesDTOList.forEach(dto -> {
                if (StringUtils.isBlank(dto.getExpressNo())) {
                    throw new ServiceResponseException(SysError.MISSING_PARAM, dto.getName() + "的快递单号不能为空!");
                }
                OrderExpress ex = new OrderExpress();
                ex.setOrderNo(express.getOrderNo());
                ex.setType(ShippingMethodEnum.EXPRESS.getId());
                ex.setName(dto.getName());
                ex.setExpressNo(dto.getExpressNo());
                expresses.add(ex);
            });
        } else if (typeEnum == ShippingMethodEnum.SELF_MENTION) {
            String expressNo = "ZT" + DateUtil.getCurrentDateTime() + StringUtil.getRandomNumber(8);
            OrderExpress ex = new OrderExpress();
            ex.setOrderNo(express.getOrderNo());
            ex.setType(ShippingMethodEnum.SELF_MENTION.getId());
            ex.setName(ShippingMethodEnum.SELF_MENTION.getName());
            ex.setExpressNo(expressNo);
            expresses.add(ex);
        }
        // 修改订单为“已发货”状态
        orderService.editExpressStatus(order.getOrderNo(), ExpressStatusEnum.SHIPPING);

        expresses.forEach(ex -> super.save(ex));

        // 保存订单发货操作日志
        StringBuilder remark = new StringBuilder();
        expresses.forEach(ex -> {
            remark.append(ex.getName() + ":" + ex.getExpressNo());
            remark.append(" ");
        });

        OrderLogs logs = new OrderLogs();
        logs.setRemark(remark.toString());
        logs.setCreateIp(IpThreadLocal.get());
        logs.setCreateDate(new Date());
        logs.setOrderNo(order.getOrderNo());
        logs.setType(OrderOpTypeEnum.SHIP_SHOPKEEPER.getId());
        logs.setOperatorId(admin.getId());
        logs.setOperatorName(admin.getUserName());
        logsService.save(logs);

        expresses.forEach(ex -> {
            //发送发货消息
            OrderShipEvent event = new OrderShipEvent(applicationContext, order.getOrderNo(), logs.getCreateDate(), ex.getName(), ex.getExpressNo());
            applicationContext.publishEvent(event);
        });
    }
}
